/**
 * @FilePath     : /src/lgmg_robots/agv_navigation/agv_navigate/include/agvNavigate/publicInterfaceInc/ros_callbacks.h
 * @Description  : 定义了ROS多个回调函数，用于处理不同的消息和服务请求，如里程计、外设状态、任务指令等。   
 * @Author       : xiujun.yang
 * @Version      : 1.0.0
 * @LastEditors  : haibo haibo.yang@lgmgim.cn
 * @LastEditTime : 2024-12-19 16:20:36
 * @Copyright (c) 2024 by 临工智能信息科技有限公司, All Rights Reserved. 
**/
#pragma once
#include "rclcpp/rclcpp.hpp"
// 2023.12.19 modify by haibo
#include <agv_msgs/msg/agv_mode.hpp>
#include <agv_srvs/srv/instant_actions.hpp>
#include <agv_srvs/srv/order.hpp>
#include <agv_msgs/msg/set_stop_bits.hpp>
#include <agv_srvs/srv/local_order.hpp>
#include <agv_msgs/msg/agv_event_status.hpp>
#include <agv_msgs/msg/recognition_result.hpp>
#include <std_srvs/srv/set_bool.hpp>

#include "steer_cmd.h"
#include "public_macro.h"

// 2024.11.8 
#include <nav_msgs/msg/odometry.hpp>
extern "C" {
    // 获取动作操作时需要的话题数据
    OpUseTopic& GetOpData();

    //   获取里程计数据
    agv_msgs::msg::OdometryLite& GetOdomData();

    // 转换里程计数据为使用的数据格式
    bool GetOdomDataHuman(Velocity& vel, float& theta);

    // 原地打舵,触发+1
    void SteerDirCmdTrig();

    // 原地打舵角发送命令逻辑
    void DoSteerCmd(const Velocity& vel, const int& steer_dir, bool open = true);

    // 原地打舵角是否完成
    bool FinishSteerCmd();

    // 清除舵命令保存的状态
    void SteerCmdClear();

    //打舵延迟是否触发
    bool SteerCmdDelayFinish(int time_ms);

    // 原地打舵反馈回调函数
    void SteerDirFeedbackCallback(const agv_msgs::msg::SteerDirFeedBack::ConstSharedPtr& data);

    // 发布舵角命令线程
    void PublishSteerCmdThread(rclcpp::Node::SharedPtr node);

    // 回调函数
    // 订阅里程记话题-回调函数
    void OdomCallback(const agv_msgs::msg::OdometryLite& msg);

    // 回调函数
    // 外设回调函数
    void PeriphStatusCallback(const agv_msgs::msg::PeriphStatus& msg);

    // 模拟量输入回调函数
    void GetAnalogCallback(const agv_msgs::msg::ReadInPutsAnalog& msg);

    // 输入io回调函数
    void ReadInputNewCallback(const agv_msgs::msg::ReadInPutsNew& msg);

    // 地面二维码回调函数
    void GetGroundCameraCallback(const geometry_msgs::msg::PoseStamped& msg);

    // 上读头二维码回调函数
    void GetRackCameraCallback(const geometry_msgs::msg::PoseStamped& msg);

    // 栈板识别结果回调函数
    void GetPalletCallback(const agv_msgs::msg::RecognitionResult &msg);

    // 订阅事件话题-回调函数 2023.12.20 modify by haibo
    void EventCallback(const agv_msgs::msg::AGVEventStatus::ConstSharedPtr& event);

    // 订阅位姿话题-回调函数
    void PoseCallback(const agv_msgs::msg::PoseWithConfidence& msg);

    // 订阅slam评分回调函数
    void SlamScoreCallback(const agv_msgs::msg::ConfidenceLevel& msg);

    // 订阅agvInfo话题-回调函数 2023.12.19 modify by haibo
    void AgvModeCallback(const agv_msgs::msg::AGVMode::ConstSharedPtr& data);

    // 订阅本地调试模式任务话题-回调函数
    bool OfflineOrderTaskCallback(const agv_srvs::srv::LocalOrder::Request::SharedPtr request,
        agv_srvs::srv::LocalOrder::Response::SharedPtr response);

    // 订阅在线订单任务话题-回调函数
    bool OrderTaskCallback(const agv_srvs::srv::Order::Request::SharedPtr request,
        agv_srvs::srv::Order::Response::SharedPtr response);

    // 订阅立即动作服务-回调函数
    bool InstantActionCallback(const agv_srvs::srv::InstantActions::Request::SharedPtr request,
        agv_srvs::srv::InstantActions::Response::SharedPtr response);

    // 获取Navigation版本
    bool GetVersion(const std_srvs::srv::SetBool::Request::SharedPtr request, 
        std_srvs::srv::SetBool::Response::SharedPtr response);

    // 订阅外设状态话题-回调函数
    void PeriphStatusCallback(const agv_msgs::msg::PeriphStatus& msg);

    // 外部设置停止位标识
    void StopBitsFeedbackCallback(const agv_msgs::msg::SetStopBits& msg);

    //  发布topic线程
    //  任务发布线程
    void TaskAndSubNavInfoThread(rclcpp::Node::SharedPtr node);

    //  导航任务发布话题数据线程
    void PublishNavVelAndStatusThread(rclcpp::Node::SharedPtr node);

    // 本地调试模式发布话题数据线程
    void AutoStatusThread(rclcpp::Node::SharedPtr node);

    // 调度模式发布话题数据线程
    void PubOnlineStateThreadFun(rclcpp::Node::SharedPtr node);

    // 其他辅助类函数
    bool IsTimeOut(const rclcpp::Time& data_time, const rclcpp::Time& cur_time, const double& max_time_ms);

    // 获取agv载货状态
    bool GetAgvLoad(bool& load);

        //设置当前设置载货标识
    bool SetLoadFlags();
}
